package com.hison.courseselectionsystem.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hison.courseselectionsystem.domain.Student;
import com.hison.courseselectionsystem.dto.LoginFormByPhone;
import com.hison.courseselectionsystem.dto.LoginFormById;
import com.hison.courseselectionsystem.service.StudentService;
import com.hison.courseselectionsystem.mapper.StudentMapper;
import com.hison.courseselectionsystem.utils.RegexUtils;
import com.hison.courseselectionsystem.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author hison
 * @description 针对表【student】的数据库操作Service实现
 * @createDate 2023-11-16 21:53:51
 */
@Service
@Slf4j
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 学生注册
     *
     * @param student
     * @return {@link Result}
     */
    @Override
    public Result register(Student student) {
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        //1.注册之前先判断当前用户是否已经存在
        if (student.getStuId() != null & student.getStuId() != "") {
            wrapper.eq("stu_id", student.getStuId());
        }
        if (student.getName() != null & student.getName() != "") {
            wrapper.eq("name", student.getName());
        }
        Student student1 = studentMapper.selectOne(wrapper);
        if (student1 != null) {
            return Result.fail("注册失败，用户已经存在");
        }
        int i = studentMapper.insert(student);
        return i > 0 ? Result.ok("注册成功") : Result.fail("注册失败，请将信息补充完整");
    }

    @Override
    public Result login(LoginFormById loginForm) {
        //1.根据学号和用户查找是否存在该用户
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stu_id", loginForm.getId());
        queryWrapper.eq("stu_pwd", loginForm.getPwd());
        Student student = studentMapper.selectOne(queryWrapper);
        if (student == null) {
            return Result.fail("用户不存在，请先注册，或者尝试使用手机号登录");
        }
        //生成随机token
        String token = UUID.randomUUID().toString(true);
        //将token存入缓存
        String tokenKey = "token:login" + token;
        //7.3存储
        //将对象转为map集合
        Map<String, Object> userMap = BeanUtil.beanToMap(student, new HashMap<>(),
                //设置忽略空值
                CopyOptions.create().setIgnoreNullValue(true)
                        //将字段的值转为string类型
                        .setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));
        stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);
        //设置token有效期  30分钟   session过期时间
        stringRedisTemplate.expire(tokenKey, 30, TimeUnit.MINUTES);
        return Result.ok(token);
    }

    @Override
    public Result login(LoginFormByPhone loginFormByPhone) {
        //1.校验手机号
        String phone = loginFormByPhone.getPhone();
        //验证手机号
        if (RegexUtils.isPhoneInvalid(phone)) {
            return Result.fail("手机号码格式错误");
        }
        //2.校验验证码
        String code = loginFormByPhone.getCode();
        String cacheCode = stringRedisTemplate.opsForValue().get("login:code" + phone);
        if (cacheCode == null || !cacheCode.equals(code)) {
            //3.不一致，报错
            return Result.fail("验证码有误");
        }
        Student student = query().eq("phone", phone).one();
        if (student == null) {
            return Result.fail("用户不存在");
        }
        //生成随机token
        String token = UUID.randomUUID().toString(true);
        //将token存入缓存
        String tokenKey = "token:login" + token;
        //7.3存储
        //将对象转为map集合
        Map<String, Object> userMap = BeanUtil.beanToMap(student, new HashMap<>(),
                //设置忽略空值
                CopyOptions.create().setIgnoreNullValue(true)
                        //将字段的值转为string类型
                        .setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));
        stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);
        //设置token有效期  30分钟   session过期时间
        stringRedisTemplate.expire(tokenKey, 30, TimeUnit.MINUTES);
        return Result.ok(token);
    }

    @Override
    public Result sendCode(String phone) {
        //1.校验手机号
        if (RegexUtils.isPhoneInvalid(phone)) {

            return Result.fail("手机号格式错误!");
        }
        String code = RandomUtil.randomNumbers(6);
        //4.保存验证码到redis
        stringRedisTemplate.opsForValue().set("login:code" + phone, code, 2, TimeUnit.MINUTES);
        //5.发送验证码   需要调用第三方平台
        System.out.println("验证码为:" + code);
        //返回ok
        return Result.ok("验证码发送成功");
    }

    @Override
    public Result getUserInfo(String stuId) {
        //获取学号   根据学号获取完整的信息
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.eq("stu_id", stuId);
        return Result.ok(studentMapper.selectOne(wrapper));
    }

    @Override
    public Result updateUser(Student student) {
        int i = studentMapper.updateById(student);
        return i > 0 ? Result.ok("更新成功") : Result.fail("更新失败");
    }

    @Override
    public Result updatepwd(String stuId, String oldpwd, String newpwd) {
        //旧密码验证
        if (stuId == null) {
            return Result.fail("用户未登录");
        }
        Map<String, String> map = new HashMap<>();
        map.put("stuId", stuId);
        map.put("newpwd", newpwd);
        studentMapper.updatepwd(map);

        return Result.ok("更新成功");

    }

    @Override
    public Result findPwd(String phone, String stuid) {
        Student stuId = query().eq("stu_id", stuid).one();
        if (stuId == null) {
            return Result.fail("用户不存在");
        }
        //返回验证码
        sendCode(phone);
        return Result.ok();
    }

}
